from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from typing import Any, Optional


@dataclass
class Submission:
    submission_id: str
    student_id: str
    assignment_id: str
    content: Any
    file_path: Optional[str] = None
    submitted_at: datetime = field(default_factory=datetime.now)
    is_late: bool = False
    grade: Optional[float] = None
    feedback: Optional[str] = None
    graded_at: Optional[datetime] = None
    status: str = "submitted"

    def submit(self) -> bool:
        self.submitted_at = datetime.now()
        self.status = "submitted"
        return True

    def update_content(self, content: Any) -> bool:
        if self.status == "graded":
            return False
        self.content = content
        self.submitted_at = datetime.now()
        return True

    def add_grade(self, score: float, feedback: Optional[str] = None) -> None:
        self.grade = float(score)
        self.feedback = feedback
        self.graded_at = datetime.now()
        self.status = "graded"

    def get_grade(self) -> Optional[float]:
        return self.grade

    def check_if_late(self, due_date: datetime) -> bool:
        # Handle timezone-aware vs naive datetime comparison
        if self.submitted_at.tzinfo is None and due_date.tzinfo is not None:
            # submitted_at is naive, due_date is aware - make both naive
            due_date_naive = due_date.replace(tzinfo=None)
            self.is_late = self.submitted_at > due_date_naive
        elif self.submitted_at.tzinfo is not None and due_date.tzinfo is None:
            # submitted_at is aware, due_date is naive - make both naive
            submitted_naive = self.submitted_at.replace(tzinfo=None)
            self.is_late = submitted_naive > due_date
        else:
            # Both have same timezone awareness
            self.is_late = self.submitted_at > due_date
        return self.is_late

    def get_info(self) -> dict:
        return {
            "submission_id": self.submission_id,
            "student_id": self.student_id,
            "assignment_id": self.assignment_id,
            "submitted_at": self.submitted_at.isoformat(),
            "is_late": self.is_late,
            "grade": self.grade,
            "status": self.status,
        }
    
    def to_dict(self) -> dict:
        """Convert to dictionary format - compatible with serialization"""
        return {
            "submission_id": self.submission_id,
            "student_id": self.student_id,
            "assignment_id": self.assignment_id,
            "content": self.content,
            "file_path": self.file_path,
            "submitted_at": self.submitted_at.isoformat() if self.submitted_at else None,
            "is_late": self.is_late,
            "grade": self.grade,
            "feedback": self.feedback,
            "graded_at": self.graded_at.isoformat() if self.graded_at else None,
            "status": self.status,
        }
    
    @classmethod
    def from_dict(cls, data: dict) -> 'Submission':
        """Create Submission object from dictionary"""
        # Handle date fields
        submitted_at = data.get('submitted_at')
        if isinstance(submitted_at, str):
            submitted_at = datetime.fromisoformat(submitted_at.replace('Z', '+00:00'))
        
        graded_at = data.get('graded_at')
        if isinstance(graded_at, str):
            graded_at = datetime.fromisoformat(graded_at.replace('Z', '+00:00'))
        
        return cls(
            submission_id=data['submission_id'],
            student_id=data['student_id'],
            assignment_id=data['assignment_id'],
            content=data.get('content'),
            file_path=data.get('file_path'),
            submitted_at=submitted_at,
            is_late=data.get('is_late', False),
            grade=data.get('grade'),
            feedback=data.get('feedback'),
            graded_at=graded_at,
            status=data.get('status', 'submitted')
        )
# Submission model